package fu.capstone.hanoicityguide.presentation.fragment.nearby;

import java.util.ArrayList;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.mapquest.android.maps.AnnotationView;
import com.mapquest.android.maps.DefaultItemizedOverlay;
import com.mapquest.android.maps.GeoPoint;
import com.mapquest.android.maps.MapView;
import com.mapquest.android.maps.MyLocationOverlay;

import fu.capstone.hanoicityguide.R;
import fu.capstone.hanoicityguide.business.bo.nearbyplace.NearbyPlaceBO;
import fu.capstone.hanoicityguide.business.bo.nearbyplace.NearbyPlaceBOImp;
import fu.capstone.hanoicityguide.business.model.Place;
import fu.capstone.hanoicityguide.common.onlinemapultility.OnlineMapUtil;
import fu.capstone.hanoicityguide.common.utility.InternetSetting;
import fu.capstone.hanoicityguide.common.utility.LocationSetting;

@SuppressLint("ValidFragment")
public class NearbyOnlineMapFragment extends Fragment {

	private MyLocationOverlay mylocationoverlay;
	private MapView map;
	private OnlineMapUtil util;
	private LocationSetting locationSetting;
	private InternetSetting internetSetting;
	private Context context;
	private NearbyPlaceBO nearbyBO;
	private ArrayList<Place> arrNearby;
	private GeoPoint nearbyplace_geo;
	private DefaultItemizedOverlay overlay;
	private MyLocationListener locationListener;
	private String keyword;
	private ArrayList<String> filter;
	private String sorter;

	public NearbyOnlineMapFragment(String keyword, ArrayList<String> filter,
			String sorter) {
		this.keyword = keyword;
		this.filter = filter;
		this.sorter = sorter;
	}

	public String getKeyword() {
		return keyword;
	}

	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}

	public ArrayList<String> getFilter() {
		return filter;
	}

	public void setFilter(ArrayList<String> filter) {
		this.filter = filter;
	}

	public String getSorter() {
		return sorter;
	}

	public void setSorter(String sorter) {
		this.sorter = sorter;
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		context = container.getContext();
		View nearby_fragment = inflater.inflate(
				R.layout.nearby_online_map_fragment, container, false);
		map = (MapView) nearby_fragment.findViewById(R.id.mapview);

		// getting GPS + internet status
		locationSetting = new LocationSetting(context);
		internetSetting = new InternetSetting(context);

		if (!locationSetting.getGPSSetting(getActivity())) {
			// Toast.makeText(context, "asdasdas", Toast.LENGTH_SHORT).show();
			locationSetting.showSettingsAlert();
		} else if (!internetSetting.getConnectivityStatus(getActivity())) {
			internetSetting.showSettingsAlert();
		} else {

			util = new OnlineMapUtil();
			util.setupmap(map);
			util.getcurrentLocation(context, map);

			mylocationoverlay = new MyLocationOverlay(context, map);
			mylocationoverlay.enableCompass();
			mylocationoverlay.enableMyLocation();

			String provider;
			LocationManager locManager = (LocationManager) context
					.getSystemService(Context.LOCATION_SERVICE);
			locationListener = new MyLocationListener();
			locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1,
					1, locationListener);

			Criteria criteria = new Criteria();
			provider = locManager.getBestProvider(criteria, false);
			Location lastKnownLoc = null;
			try {
				lastKnownLoc = locManager
						.getLastKnownLocation(LocationManager.GPS_PROVIDER);
				// GeoPoint currentLocation = new
				// GeoPoint(lastKnownLoc.getLatitude(),
				// lastKnownLoc.getLongitude());
			} catch (NullPointerException e) {
				Log.e("Nearby Fragment", e.toString());
			}
			nearbyBO = new NearbyPlaceBOImp(context);
			arrNearby = nearbyBO.listNearbyPlace(lastKnownLoc.getLatitude(),
					lastKnownLoc.getLongitude(), 1000, getKeyword(),
					getFilter(), getSorter());

			// compare to radius, remove outer points
			if (arrNearby.size() != 0) {
				for (int i = 0; i < arrNearby.size(); i++) {
					Location tempLocation = new Location("TempLocation " + i);
					tempLocation.setLatitude(arrNearby.get(i).getGeo()
							.getLatitude());
					tempLocation.setLongitude(arrNearby.get(i).getGeo()
							.getLongitude());

					double distance = tempLocation.distanceTo(lastKnownLoc);
					if (distance > 1000) {
						arrNearby.remove(i);
					}
				}
			}

			if (arrNearby.size() == 0 || arrNearby == null) {
				AlertDialog.Builder alertDialog = new AlertDialog.Builder(
						context);
				alertDialog.setTitle("Nearby Places");
				alertDialog.setMessage("Sorry! No nearby place detected");
				alertDialog.setNegativeButton("OK", new OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						dialog.cancel();
					}
				});
			}

			Drawable icon = context.getResources().getDrawable(
					R.drawable.location_marker);
			overlay = new DefaultItemizedOverlay(icon);
			// create marker of given points
			for (int i = 0; i < arrNearby.size(); i++) {
				nearbyplace_geo = util.convertGeocoordinatetoGeopoint(arrNearby
						.get(i).getGeo());
				util.createMarker(context, map, overlay, nearbyplace_geo,
						arrNearby.get(i).getName(), arrNearby.get(i).getType());
			}
		}

		return nearby_fragment;

	}

	public NearbyOnlineMapFragment() {
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.v("Map online nearby on destroy", "destroyed");
		LocationManager locManager = (LocationManager) getActivity()
				.getSystemService(Context.LOCATION_SERVICE);
		try {
			locManager.removeUpdates(locationListener);
			locManager = null;
			mylocationoverlay.destroy();
			mylocationoverlay.disableMyLocation();
			mylocationoverlay.disableCompass();
		} catch (Exception e) {
		}
	}

	public class MyLocationListener implements LocationListener {

		@Override
		public void onLocationChanged(Location arg0) {
			// TODO Auto-generated method stub

			overlay.destroy();
			AnnotationView annotation = util.getAnnotation();
			annotation.hide();
			util.getcurrentLocation(getActivity(), map);

			String provider;
			LocationManager locManager = (LocationManager) getActivity()
					.getSystemService(Context.LOCATION_SERVICE);
			Criteria criteria = new Criteria();
			provider = locManager.getBestProvider(criteria, false);
			Location lastKnownLoc = null;

			try {
				lastKnownLoc = locManager.getLastKnownLocation(provider);
				arrNearby = new ArrayList<Place>();
				arrNearby = nearbyBO.listNearbyPlace(
						lastKnownLoc.getLatitude(),
						lastKnownLoc.getLongitude(), 1000, getKeyword(),
						getFilter(), getSorter());
				// compare to radius, remove outer points
				if (arrNearby.size() != 0) {
					for (int i = 0; i < arrNearby.size(); i++) {
						Location tempLocation = new Location("TempLocation "
								+ i);
						tempLocation.setLatitude(arrNearby.get(i).getGeo()
								.getLatitude());
						tempLocation.setLongitude(arrNearby.get(i).getGeo()
								.getLongitude());

						double distance = tempLocation.distanceTo(lastKnownLoc);
						if (distance > 1000) {
							arrNearby.remove(i);
						}
					}
				}

				if (arrNearby.size() == 0 || arrNearby == null) {
					AlertDialog.Builder alertDialog = new AlertDialog.Builder(
							getActivity());
					alertDialog.setTitle("Nearby Places");
					alertDialog.setMessage("Sorry! No nearby place detected");
					alertDialog.setNegativeButton("OK", new OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							// TODO Auto-generated method stub
							dialog.cancel();
						}
					});
				}

				Drawable icon = context.getResources().getDrawable(
						R.drawable.location_marker);
				overlay = new DefaultItemizedOverlay(icon);
				// create marker of given points
				for (int i = 0; i < arrNearby.size(); i++) {
					nearbyplace_geo = util
							.convertGeocoordinatetoGeopoint(arrNearby.get(i)
									.getGeo());
					util.createMarker(context, map, overlay, nearbyplace_geo,
							arrNearby.get(i).getName(), arrNearby.get(i)
									.getType());
				}

			} catch (NullPointerException e) {
				Log.e("Nearby Fragment", e.toString() + "");
			}
		}

		@Override
		public void onProviderDisabled(String arg0) {
			// TODO Auto-generated method stub
			locationSetting.showSettingsAlert();
		}

		@Override
		public void onProviderEnabled(String arg0) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
			// TODO Auto-generated method stub

		}
	}
}
